#!/usr/bin/python

"""
 Module: maingui.py
  Ver: 1.0.0; (original version) Rev Last: 12/24/2012 - Previous: 12/22/2012
  Original Releasez; 12/24/2012

 Rev 1.0.1; Last: 01/25/2013 - Previous: 01/25/2013 (AEM)
   - Update inital set selection logic to reset Stream Select drop
     down box and end time box to values used on last session.
   - Updated associated comments


 Rev 1.0.2; Last: 02/07/2013 - Previous: 01/25/2013 (AEM)
   - Add File Clean and Move menu

  Set and control stream action panel and connect info panel gui components
  in the getnetstream main panels.

 Copyright (C) 2012-2013  Arnold E. Morgan

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

"""

import wx
import time

CurrentStreamItem = -1     # Current record in the wx.ListCtrl
# ----------------------------------------------------------------------------


def init_sizers(myself):
   """ Establish the main frame sizers and set their colors.

   Will only be called at application start up time.
   """

   myself.vbox0 = wx.BoxSizer(wx.VERTICAL)

   myself.StreamListPanel = wx.Panel(myself, wx.ID_ANY,
                                     style=wx.SUNKEN_BORDER)
   myself.StreamActionPanel = wx.Panel(myself, wx.ID_ANY,
                                       style=wx.SUNKEN_BORDER)
   myself.ConnectInfoPanel = wx.Panel(myself, wx.ID_ANY,
                                      style=wx.SUNKEN_BORDER)

   myself.StreamListPanel.SetBackgroundColour("#B0E2FF")
   #myself.StreamActionPanel.SetBackgroundColour("#F5F5F5")
   #myself.ConnectInfoPanel.SetBackgroundColour('#F5F5F5')
   #myself.StreamActionPanel.SetBackgroundColour("#07AAF0")
   #myself.ConnectInfoPanel.SetBackgroundColour('#07AAF0')

   #myself.StreamActionPanel.SetBackgroundColour("#2CB7F3")
   #myself.ConnectInfoPanel.SetBackgroundColour('#2CB7F3')
   myself.StreamActionPanel.SetBackgroundColour(myself.IdlePanelColor)
   myself.ConnectInfoPanel.SetBackgroundColour(myself.IdlePanelColor)

   myself.vbox = wx.BoxSizer(wx.VERTICAL)
   myself.vbox.Add(myself.StreamListPanel, 1, wx.EXPAND)
   myself.vbox0.Add(myself.vbox, 5,
                    wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)


def set_stream_action_panel(myself):
   """ Define all controls inside the Stream Action panel.

   Will only be called at application start up time.
   """

   myself.StreamActionLabelPanel = wx.Panel(myself.StreamActionPanel,
                                            wx.ID_ANY, pos=(60, 6),
                                            size=(402, 40),
                                            style=wx.BORDER_RAISED)

   myself.StreamActionLbl = wx.StaticText(myself.StreamActionLabelPanel,
                                          wx.ID_ANY,
                                '********** Stream Action Info **********',
                                          (28, 10))
   myself.StreamActionLbl.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
   # --------------------------------------------------------------------


def set_connect_info_panel(myself):
   """ Define all controls inside the Connect Info panel.

   Will only be called at application start up time.
   """

   myself.ConnectLabelPanel = wx.Panel(myself.ConnectInfoPanel, wx.ID_ANY,
                                       pos=(45, 6), size=(330, 40),
                                       style=wx.BORDER_RAISED)

   myself.ConnectActionLbl = wx.StaticText(myself.ConnectLabelPanel, wx.ID_ANY,
                                    '********** Connect Info **********',
                                           (20, 10))
   myself.ConnectActionLbl.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
   # --------------------------------------------------------------------


def show_stream_ctrls(myself, StreamList):
   """ Define all the detail application button, text box, combo box, label
   controls.

   Also bind any needed event methods.
   Will only be called at application start up time.
   """

   init_stream_list_ctrl(myself)
   myself.StreamCtrlbox = wx.StaticBox(myself.StreamActionPanel, wx.ID_ANY,
                                       label="  Stream Settings  ",
                                       pos=wx.Point(40, 60),
                                       size=wx.Size(450, 400), style=0)

   myself.StreamCtrlsizer = wx.StaticBoxSizer(myself.StreamCtrlbox,
                                              wx.VERTICAL)

   # -------------------- Default Labels -------------------------
   # Reset the stream source name to the last value used.
   try:
      LastIndex = StreamList.index(myself.LastStreamName)
   except ValueError:
      LastIndex = 0

   myself.ActiveText = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                     'Active Stream', (90, 100))

   myself.ActiveName = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                     StreamList[LastIndex], (100, 120))

   myself.ActiveURL = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                    myself.StreamURL[LastIndex], (100, 140))

   myself.ActiveLoc = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                    myself.StreamLoc[LastIndex], (100, 160))

   # -------------------- buttons -------------------------
   myself.ActionText = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                     '---------- Stream Actions ----------',
                                    (160, 345))
   myself.StartButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
                                  label="Start", pos=wx.Point(100, 370))
   myself.PauseButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
                                  label="Pause", pos=wx.Point(220, 370))
   myself.DoneButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
                                 label=" End Session ", pos=wx.Point(340, 370))

   # *** Disable this button while stream capture is in progress ***
   myself.ClearListButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
                                      label="Clear", pos=wx.Point(100, 410))

   #*** DEBUG: test button new functions ***
   #myself.TestButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
   #                                       label="Test",
   #                                       pos=wx.Point(220, 410))

   #*** Another debug ctrl ***
   #myself.UpdateStreamButton = wx.Button(myself.StreamActionPanel, wx.ID_ANY,
   #                                      label="T-Update",
   #                                      pos=wx.Point(340, 410))

   # -------------------- drop down box -------------------------
   myself.SelectText = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                     'Available Streams:', (90, 205))
   #myself.SelectText.SetForegroundColour((255,255,255))
   myself.SelectText.SetForegroundColour((0, 0, 0))

   myself.StreamSelect = wx.ComboBox(myself.StreamActionPanel, wx.ID_ANY,
                                     StreamList[0],  (90, 225), (190, -1),
                                     StreamList, wx.CB_DROPDOWN)

   myself.StreamSelect.SetSelection(LastIndex)
   myself.StreamSelect.Bind(wx.EVT_COMBOBOX,
                            myself.new_stream_selected)

   # -------------------- End Time -------------------------
   myself.EndText = wx.StaticText(myself.StreamActionPanel, wx.ID_ANY,
                                  'End Time (hh:mm)', (90, 280))
   myself.EndTimeBox = wx.TextCtrl(myself.StreamActionPanel, wx.ID_ANY,
                                   value="", pos=(90, 300), size=(60, 24))
   myself.EndTimeBox.SetMaxLength(5)
   myself.EndTimeBox.SetValue(myself.LastEndTime)
   myself.EndTimeBox.Bind(wx.EVT_ENTER_WINDOW, myself.show_end_time_help)
   # -------------------- Add to sizer -------------------------
   myself.StreamCtrlsizer.Add(myself.StartButton)
   myself.StreamCtrlsizer.Add(myself.PauseButton)
   myself.StreamCtrlsizer.Add(myself.DoneButton)
   myself.StreamCtrlsizer.Add(myself.ClearListButton)
   myself.StreamCtrlsizer.Add(myself.StreamSelect, flag=wx.GROW)
   #myself.StreamCtrlsizer.Add(myself.TestButton)
   #myself.StreamCtrlsizer.Add(myself.UpdateStreamButton)

   # -------------------- Bind Events -------------------------
   myself.StartButton.Bind(wx.EVT_BUTTON, myself.start_stream)
   myself.DoneButton.Bind(wx.EVT_BUTTON, myself.end_stream_session)
   myself.ClearListButton.Bind(wx.EVT_BUTTON, myself.clear_stream_list_content)

   # *** Re-enable the 'Clear' button when the 'Pause' button is clicked ***
   myself.PauseButton.Bind(wx.EVT_BUTTON, myself.pause_stream)
   #myself.TestButton.Bind(wx.EVT_BUTTON, myself.on_new_dir)

   #*** These deactivate the click events for these ctrls ***
   #myself.StreamSelect.Bind(wx.EVT_ENTER_WINDOW, myself.StreamSelectHover)
   #myself.StartButton.Bind(wx.EVT_ENTER_WINDOW, myself.StartBttnHover)
   #myself.PauseButton.Bind(wx.EVT_ENTER_WINDOW, myself.PauseBttnHover)
   #myself.ClearListButton.Bind(wx.EVT_ENTER_WINDOW, myself.ClearListBttnHover)
   #myself.EndTimeBox.Bind(wx.EVT_ENTER_WINDOW, myself.ShowEndTimeHelp)

   # -----------------------------------------------------------
   myself.StreamConnectList = wx.ListBox(myself.ConnectInfoPanel, wx.ID_ANY,
                                        (20, 66), (378, 400), choices=[],
                                         style=wx.LB_HSCROLL)

   myself.ClearConnectButton = wx.Button(myself.ConnectInfoPanel, wx.ID_ANY,
                                         label="Clear List",
                                         pos=wx.Point(20, 480))

   myself.ClearConnectButton.Bind(wx.EVT_BUTTON, myself.clear_connect_items)
   #myself.ClearConnectButton.Bind(wx.EVT_ENTER_WINDOW,
   #                               myself.ClearConnectBttnHover)
   # -------------------------------------------------------------------------


def get_stream_session_vals(myself, UpdateLabels=False):
   """ Retrieve all session values.

   The StreamName value establishes the index offset into
   the list structures that hold all other supporting values.

   Input Arg:
     UpdateLabels - If supplied also update the text labels.
                    value is optional.
   Return Val:
     StreamSession - dictionary structure of session values.
   """

   StreamSession = {}
   StreamSession['StreamName'] = myself.StreamSelect.GetValue()
   StreamIdx = myself.StreamSelect.GetSelection()
   StreamSession['StreamURL'] = myself.StreamURL[StreamIdx]
   StreamSession['StreamLoc'] = myself.StreamLoc[StreamIdx]
   StreamSession['StreamET'] = myself.EndTimeBox.GetValue()

   # If a value is chosen from the select box, update the labels.
   if UpdateLabels:
      set_stream_labels(myself, StreamSession)

   return StreamSession
   # -------------------------------------------------------------------------


def set_stream_labels(myself, StreamLabels):
   """ Does exactly what it says. """

   LabelName = StreamLabels['StreamName']
   if len(LabelName) > 52:
      LabelName = StreamLabels['StreamName'][0:52] + "..."
   myself.ActiveName.SetLabel(LabelName)

   LabelName = StreamLabels['StreamURL']
   if len(LabelName) > 52:
      LabelName = StreamLabels['StreamURL'][0:52] + "..."
   myself.ActiveURL.SetLabel(LabelName)

   LabelName = StreamLabels['StreamLoc']
   if len(LabelName) > 52:
      LabelName = StreamLabels['StreamLoc'][0:52] + "..."
   myself.ActiveLoc.SetLabel(LabelName)
   # -------------------------------------------------------------------------


def AddConnectItem(myself, NewStrItem):
   """ Add a single item to the StreamConnectList wx.ListBox control. """

   myself.StreamConnectList.Append(NewStrItem)
   # -------------------------------------------------------------------------


def add_connect_items(myself, NewStrItems):
   """ Add multiple items to the StreamConnectList wx.ListBox control. """

   TempTime = time.strftime("%H:%M:%S", time.localtime())
   myself.StreamConnectList.Append('Start Time: ' + TempTime)
   myself.StreamConnectList.AppendItems(NewStrItems)
   #for OneItem in NewStrItems:
   #   myself.StreamConnectList.Append(OneItem)
   # -------------------------------------------------------------------------


def init_stream_list_ctrl(myself):
   """ Define the wx.ListCtrl with its column title values. """

   myself.StreamListCtrl = wx.ListCtrl(myself.StreamListPanel, -1, pos=(3, 1),
                                       size=(970, 265),
                                       style=wx.LC_REPORT |
                                       wx.BORDER_SUNKEN | wx.LC_HRULES)

   #*** List of tuple column assignments ***
   ColData = [(0, 65, "Step"), (1, 895, "Stream Progress")]

   myself.StreamListCtrl.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL))

   for (ColIndex, ColWidth, ColTitle) in ColData:
      myself.StreamListCtrl.InsertColumn(ColIndex, ColTitle)
      myself.StreamListCtrl.SetColumnWidth(ColIndex, ColWidth)
   # -------------------------------------------------------------------------


def disable_stream_action_ctrls(myself):
   """ Stream session starting, disable all controls so we don't do
   mean things while the thread and subprocess are active.
   """

   myself.StreamActionPanel.SetBackgroundColour(myself.LivePanelColor)
   myself.ConnectInfoPanel.SetBackgroundColour(myself.LivePanelColor)

   myself.ImportStreamMenu.Enable(False)
   myself.LogStreamMenu.Enable(False)
   myself.ExitItem.Enable(False)
   myself.AboutItem.Enable(False)
   myself.FileCleanMoveMenu.Enable(False)

   myself.StartButton.Enable(False)
   myself.ClearListButton.Enable(False)
   myself.ClearConnectButton.Enable(False)
   myself.StreamSelect.Enable(False)
   myself.EndTimeBox.Enable(False)
   # -------------------------------------------------------------------------


def enable_stream_action_ctrls(myself):
   """ Stream session is over, re-enable all controls. """

   myself.StreamActionPanel.SetBackgroundColour(myself.IdlePanelColor)
   myself.ConnectInfoPanel.SetBackgroundColour(myself.IdlePanelColor)

   myself.ImportStreamMenu.Enable(True)
   myself.LogStreamMenu.Enable(True)
   myself.ExitItem.Enable(True)
   myself.AboutItem.Enable(True)
   myself.FileCleanMoveMenu.Enable(True)

   myself.StartButton.Enable(True)
   myself.ClearListButton.Enable(True)
   myself.ClearConnectButton.Enable(True)
   myself.StreamSelect.Enable(True)
   myself.EndTimeBox.Enable(True)
   # -------------------------------------------------------------------------


def insert_new_stream_list_item(myself, RowStr):
   """ Add a new row and item to the StreamList ws.ListCtrl. """

   global CurrentStreamItem
   CurrentStreamItem += 1
   myself.StreamListCtrl.InsertStringItem(CurrentStreamItem,
                                          str(CurrentStreamItem))
   myself.StreamListCtrl.SetStringItem(CurrentStreamItem, 1, RowStr)
   # -------------------------------------------------------------------------


def update_stream_list_item(myself, RowStr):
   """ Update the current row of the StreamList wx.ListCtrl. """

   global CurrentStreamItem
   if myself.StreamListCtrl.GetItemCount() > 0:
      myself.StreamListCtrl.SetStringItem(CurrentStreamItem, 1, RowStr)
   else:
      insert_new_stream_list_item(myself, RowStr)
   # -------------------------------------------------------------------------
